home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Software of the Month Club
/
Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].zip
/
Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].adf
/
Typeface
/
Source
/
preview.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-01
|
14KB
|
513 lines
/*******************/
/* */
/* Font Previewing */
/* */
/*******************/
#include "Typeface.h"
struct Window *PreviewWnd;
struct ClipboardHandle *Clip, *Undo;
Object *PreviewWndObj, *PreviewStr, *PreviewScroll;
UBYTE *PreviewFont;
struct TextFont *tfh;
struct NewMenu PreviewMenus[] = { PROJECT_MENU,FONT_MENU,PREVIEW_MENU,End };
extern struct Screen *Screen;
extern struct MsgPort *WndMsgPort;
extern struct Character CharBuffer[257];
extern struct Window *SaveWnd;
extern Object *SaveWndObj;
extern ULONG FirstChar, LastChar;
void OpenPreviewWnd(void)
{
Object *all, *cancel, *update, *clear;
if (PreviewWnd)
{
WindowToFront(PreviewWnd);
ActivateWindow(PreviewWnd);
SetPreviewFont();
SetPreviewScroller();
ActivateGadget(PreviewStr,PreviewWnd,NULL);
}
else
{
if (PreviewWndObj == NULL)
{
Clip = OpenClipboard(PRIMARY_CLIP);
Undo = OpenClipboard(1);
SetupMenus(PreviewMenus);
PreviewWndObj = WindowObject,
WINDOW_Screen,Screen,
WINDOW_SharedPort,WndMsgPort,
WINDOW_MenuStrip,PreviewMenus,
WINDOW_Title,GetString(msgPreviewTitle),
WINDOW_HelpFile,NAME".guide",
WINDOW_HelpNode,"preview",
WINDOW_ScaleWidth,70,
WINDOW_ScaleHeight,70,
WINDOW_SmartRefresh,TRUE,
WINDOW_CloseOnEsc,TRUE,
WINDOW_MasterGroup,
VGroupObject,
HOffset(SizeX(8)),VOffset(SizeY(4)),Spacing(SizeY(4)),
GROUP_BackFill,SHINE_RASTER,
StartMember,
HGroupObject,
HOffset(SizeX(8)),VOffset(SizeY(4)),
ButtonFrame,
FRM_Recessed,TRUE,
StartMember,
PreviewStr = ExternalObject,
EXT_Class,TEXTFIELD_GetClass(),
EXT_NoRebuild,TRUE,
TEXTFIELD_BlockCursor,TRUE,
TEXTFIELD_Border,TEXTFIELD_BORDER_DOUBLEBEVEL,
TEXTFIELD_PassCommand,TRUE,
TEXTFIELD_NonPrintChars,TRUE,
TEXTFIELD_ClipStream,Clip,
TEXTFIELD_UndoStream,Undo,
GA_ID,ID_PREVIEWSTR,
EndObject,
EndMember,
StartMember,
PreviewScroll = VertScroller(NULL,0,0,0,ID_PREVIEWSCROLL),
FixMinWidth,
EndMember,
EndObject,
EndMember,
StartMember,
HGroupObject,
Spacing(SizeX(8)),
EqualWidth,
StartMember,
update = KeyButton(GetString(gadgUpdate),ID_UPDATE),
EndMember,
StartMember,
all = KeyButton(GetString(gadgShowAll),ID_ALL),
EndMember,
StartMember,
clear = KeyButton(GetString(gadgClear),ID_CLEAR),
EndMember,
StartMember,
cancel = KeyButton(GetString(gadgCancel),ID_CANCEL),
EndMember,
EndObject,
FixMinHeight,
EndMember,
EndObject,
EndObject;
if (PreviewWndObj == NULL) ErrorCode(NEWWINDOW);
SetLabelKey(PreviewWndObj,update,gadgUpdate);
SetLabelKey(PreviewWndObj,all,gadgShowAll);
SetLabelKey(PreviewWndObj,clear,gadgClear);
SetLabelKey(PreviewWndObj,cancel,gadgCancel);
}
SetPreviewFont();
if ((PreviewWnd = WindowOpen(PreviewWndObj)) == NULL)
ErrorCode(OPENWINDOW);
SetPreviewScroller();
ActivateGadget(PreviewStr,PreviewWnd,NULL);
}
}
void ClosePreviewWnd(BOOL all)
{
ClrWindowClose(&PreviewWndObj,&PreviewWnd);
if (all)
{
ClrDisposeObject(&PreviewWndObj);
if (Clip) { CloseClipboard(Clip); Clip = NULL; }
if (Undo) { CloseClipboard(Undo); Undo = NULL; }
if (PreviewFont) { FreeVec(PreviewFont); PreviewFont = NULL; }
}
}
void SetPreviewFont()
{
ULONG fchar, lchar;
UBYTE *oldfont;
oldfont = PreviewFont;
fchar = FirstChar;
lchar = LastChar;
FirstChar = 0;
LastChar = 255;
PreviewFont = SaveFont(TRUE,TRUE);
FirstChar = fchar;
LastChar = lchar;
if (PreviewWnd)
{
SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
}
else
{
SetAttrs(PreviewStr,
TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
}
if (oldfont) FreeVec(oldfont);
}
void PreviewMsgs(ULONG code)
{
ULONG top;
switch (code)
{
case ID_CLEAR:
SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
TEXTFIELD_Text,"",TAG_DONE);
ActivateGadget(PreviewStr,PreviewWnd,NULL);
break;
case ID_ALL:
PreviewAll();
break;
case ID_UPDATE:
SetPreviewFont();
break;
case ID_PREVIEWSCROLL:
GetAttr(PGA_Top,PreviewScroll,&top);
SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
TEXTFIELD_Top,top,TAG_DONE);
break;
case ID_PREVIEWSTR:
SetPreviewScroller();
break;
default:
SharedMsgs(code,NULL);
break;
}
}
void SetPreviewScroller()
{
ULONG lines,visible,top;
GetAttr(TEXTFIELD_Lines,PreviewStr,&lines);
GetAttr(TEXTFIELD_Visible,PreviewStr,&visible);
GetAttr(TEXTFIELD_Top,PreviewStr,&top);
SetGadgetAttrs(PreviewScroll,PreviewWnd,NULL,
PGA_Total,lines,
PGA_Visible,visible,
PGA_Top,top,TAG_DONE);
}
#define PREVIEW_WIDTH 32
void PreviewAll(void)
{
int i,j;
char listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))+1];
for (i = 0; i < 256/PREVIEW_WIDTH; i++)
{
for (j = 0; j < PREVIEW_WIDTH; j++)
{
switch ((i*PREVIEW_WIDTH)+j)
{
case '\0':
case '\n':
case 0x0D:
listtext[(i*(PREVIEW_WIDTH+1))+j] = ' ';
break;
default:
listtext[(i*(PREVIEW_WIDTH+1))+j] = (i*PREVIEW_WIDTH)+j;
break;
}
}
listtext[(i*(PREVIEW_WIDTH+1))+PREVIEW_WIDTH] = '\n';
}
listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))] = '\0';
SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
TEXTFIELD_Text,listtext,TAG_DONE);
ActivateGadget(PreviewStr,PreviewWnd,NULL);
}
UBYTE *SaveFont(BOOL tables,BOOL preview)
{
char fontpath[256], filename[256], datestr[LEN_DATSTRING];
ULONG filesize = 0, numchars, bitwidth = 0, i, offbit, hunkstart;
struct DateTime dt;
struct DiskFontHeader *dfh;
struct FontContentsHeader *fch;
ULONG *longptr, *relocstart;
UBYTE *buffer, *mptr, *fontdataptr;
struct charDef *fontlocptr;
WORD *fontkernptr;
BPTR fontfile, contfile, lock;
extern ULONG Proportional, Normal, Bold, Italic, ULine, Extended, Reversed;
extern ULONG Height, Width, Baseline, Smear, Aspect;
extern WORD SpaceTable[257], KernTable[257];
extern BOOL DataChanged;
extern char SavePath[256], FontName[256];
strcpy(fontpath,SavePath);
AddPart(fontpath,FontName,256);
sprintf(filename,"%s/%ld",fontpath,Height);
DateStamp(&(dt.dat_Stamp));
dt.dat_Format = FORMAT_CDN;
dt.dat_Flags = 0;
dt.dat_StrDay = NULL;
dt.dat_StrDate = datestr;
dt.dat_StrTime = NULL;
DateToStr(&dt);
while ((mptr = strchr(datestr,'-')) != NULL) *mptr = '.';
numchars = LastChar-FirstChar+2;
filesize += 14*4; /* Hunk structure */
filesize += sizeof(struct DiskFontHeader);
filesize += 4*4; /* Relocatable addresses */
for (i = FirstChar; i < LastChar+1; i++)
bitwidth += (CharBuffer+i)->chr_Width;
bitwidth += (CharBuffer+256)->chr_Width;
if (bitwidth % 16 > 0) bitwidth = ((bitwidth/16)+1)*16;
filesize += (bitwidth/8)*Height; /* Character data */
filesize += numchars*sizeof(struct charDef);
if (tables)
{
filesize += numchars*4; /* Space and kern tables */
filesize += 2*4; /* Table relocs */
}
if (filesize % 4 > 0) filesize = ((filesize/4)+1)*4;
if ((buffer = AllocVec(filesize,MEMF_CLEAR)) != NULL)
{
longptr = buffer;
*longptr++ = 0x000003F3; /* Hunk structure */
*longptr++ = 0x00000000;
*longptr++ = 0x00000001;
*longptr++ = 0x00000000;
*longptr++ = 0x00000000;
*longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
*longptr++ = 0x000003E9; /* Hunk size (twice) */
*longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
if (preview)
hunkstart = 0;
else
hunkstart = longptr; /* All relocs relative to here */
*longptr++ = 0x70FF4E75; /* MOVEQ #-1,D0 RTS */
relocstart = buffer+filesize-((9+(tables ? 2 : 0))*4);
dfh = longptr;
dfh->dfh_DF.ln_Type = NT_FONT;
dfh->dfh_DF.ln_Name = (UBYTE *)((ULONG)dfh->dfh_Name-hunkstart);
dfh->dfh_FileID = DFH_ID;
sprintf(dfh->dfh_Name,"$VER: %s%d 39.0 (%s)",FontName,Height,datestr);
fontdataptr = ((UBYTE *)dfh)+sizeof(struct DiskFontHeader);
fontlocptr = fontdataptr+((bitwidth/8)*Height);
if ((ULONG)fontlocptr % 2 > 0)
fontlocptr = (struct charDef *)((((ULONG)fontlocptr/2)+1)*2);
fontkernptr = (UBYTE *)fontlocptr + numchars*sizeof(struct charDef);
tfh = &(dfh->dfh_TF);
tfh->tf_Message.mn_Node.ln_Type = NT_FONT;
tfh->tf_Message.mn_Node.ln_Name = dfh->dfh_DF.ln_Name;
tfh->tf_YSize = Height;
if (Normal == FALSE)
{
if (Bold) tfh->tf_Style |= FSF_BOLD;
if (Italic) tfh->tf_Style |= FSF_ITALIC;
if (ULine) tfh->tf_Style |= FSF_UNDERLINED;
if (Extended) tfh->tf_Style |= FSF_EXTENDED;
}
else tfh->tf_Style = FS_NORMAL;
tfh->tf_Flags = FPF_DESIGNED|FPF_DISKFONT;
if (Proportional) tfh->tf_Flags |= FPF_PROPORTIONAL;
if (Reversed) tfh->tf_Flags |= FPF_REVPATH;
switch (Aspect)
{
case 1:
tfh->tf_Flags |= FPF_TALLDOT;
break;
case 2:
tfh->tf_Flags |= FPF_WIDEDOT;
break;
}
tfh->tf_XSize = Width;
tfh->tf_Baseline = Baseline;
tfh->tf_BoldSmear = Smear;
tfh->tf_LoChar = FirstChar;
tfh->tf_HiChar = LastChar;
tfh->tf_CharData = (UBYTE *)((ULONG)fontdataptr-hunkstart);
tfh->tf_Modulo = bitwidth/8;
tfh->tf_CharLoc = (UBYTE *)((ULONG)fontlocptr-hunkstart);
if (tables)
{
tfh->tf_CharSpace = (UBYTE *)((ULONG)fontkernptr-hunkstart);
tfh->tf_CharKern =
(UBYTE *)((ULONG)fontkernptr+(numchars*2)-hunkstart);
}
for (i = FirstChar, offbit = 0; i < LastChar+1; i++)
{
WriteCharData(fontlocptr,fontdataptr,i-FirstChar,i,&offbit,bitwidth/8);
if (tables)
{
*(fontkernptr+(i-FirstChar)) = SpaceTable[i];
*(fontkernptr+(i-FirstChar+numchars)) = KernTable[i];
}
}
WriteCharData(fontlocptr,fontdataptr,numchars-1,256,&offbit,bitwidth/8);
if (tables)
{
*(fontkernptr+(numchars-1)) = SpaceTable[256];
*(fontkernptr+(numchars-1+numchars)) = KernTable[256];
}
*relocstart++ = 0x000003EC; /* Reloc structure */
*relocstart++ = 4 + (tables ? 2 : 0);
*relocstart++ = 0x00000000;
if (tables)
{
*relocstart++ = (ULONG)(&(tfh->tf_CharKern))-hunkstart;
*relocstart++ = (ULONG)(&(tfh->tf_CharSpace))-hunkstart;
}
*relocstart++ = (ULONG)(&(tfh->tf_CharLoc))-hunkstart;
*relocstart++ = (ULONG)(&(tfh->tf_CharData))-hunkstart;
*relocstart++ = (ULONG)(&(tfh->tf_Message.mn_Node.ln_Name))-hunkstart;
*relocstart++ = (ULONG)(&(dfh->dfh_DF.ln_Name))-hunkstart;
*relocstart++ = 0x00000000;
*relocstart++ = 0x000003F2;
if (preview) return (buffer);
WindowBusy(SaveWndObj);
lock = Lock(fontpath,ACCESS_READ);
WindowReady(SaveWndObj);
if (lock == 0)
{
if (SaveShowReq(GetString(msgSaveNoDir),GetString(msgSaveNoDirGadgets),
fontpath))
{
WindowBusy(SaveWndObj);
lock = CreateDir(fontpath);
WindowReady(SaveWndObj);
if (lock == 0)
{
SaveShowReq(GetString(msgSaveCreateError),GetString(msgCancel),
fontpath);
if (buffer) FreeVec(buffer);
return;
}
else UnLock(lock);
}
else
{
if (buffer) FreeVec(buffer);
return;
}
}
else UnLock(lock);
WindowBusy(SaveWndObj);
lock = Lock(filename,ACCESS_READ);
WindowReady(SaveWndObj);
if (lock)
{
UnLock(lock);
if (!SaveShowReq(GetString(msgSaveWarnExists),
GetString(msgSaveWarnExistsGadgets),filename))
{
if (buffer) FreeVec(buffer);
return;
}
}
WindowBusy(SaveWndObj);
fontfile = Open(filename,MODE_NEWFILE);
WindowReady(SaveWndObj);
if (fontfile)
{
WindowBusy(SaveWndObj);
Write(fontfile,buffer,filesize);
Close(fontfile);
DataChanged = FALSE;
lock = Lock(SavePath,ACCESS_READ);
WindowReady(SaveWndObj);
if (lock != 0)
{
sprintf(filename,"%s.font",fontpath);
WindowBusy(SaveWndObj);
fch = NewFontContents(lock,FilePart(filename));
WindowReady(SaveWndObj);
if (fch != NULL)
{
WindowBusy(SaveWndObj);
contfile = Open(filename,MODE_NEWFILE);
WindowReady(SaveWndObj);
if (contfile != 0)
{
WindowBusy(SaveWndObj);
Write(contfile,fch,sizeof(struct FontContentsHeader)+
(fch->fch_NumEntries*sizeof(struct FontContents)));
Close(contfile);
WindowReady(SaveWndObj);
}
else SaveShowReq(GetString(msgSaveWriteHeader),
GetString(msgCancel),filename);
DisposeFontContents(fch);
}
else ShowReq(GetString(msgSaveCreateHeader),GetString(msgCancel));
UnLock(lock);
}
}
else SaveShowReq(GetString(msgSaveWriteData),GetString(msgCancel),
filename);
}
else SaveShowReq(GetString(msgSaveNoMemory),GetString(msgCancel));
if (buffer) FreeVec(buffer);
FlushAllFonts();
return (NULL);
}
ULONG SaveShowReq(char *text,char *gadgets,...)
{
va_list va;
struct EasyStruct req =
{ sizeof(struct EasyStruct),0,NAME,NULL,NULL };
ULONG retcode;
if (SaveWnd == NULL) return (0);
WindowBusy(SaveWndObj);
req.es_TextFormat = text;
req.es_GadgetFormat = gadgets;
va_start(va,gadgets);
retcode = EasyRequestArgs(SaveWnd,&req,NULL,va);
va_end(va);
WindowReady(SaveWndObj);
return (retcode);
}
void WriteCharData(struct charDef *cd, UBYTE *fontdataptr, ULONG dest,
ULONG src, ULONG *off, ULONG mod)
{
struct Character *chr;
UBYTE *data;
ULONG i,j,width,widthi,modi,offset;
chr = CharBuffer+src;
data = (chr->chr_Data == NULL) ?
(CharBuffer+256)->chr_Data : chr->chr_Data;
width = chr->chr_Width;
offset = *off;
for (i = 0; i < chr->chr_Height; i++)
{
modi = mod*i;
widthi = width*i;
for (j = 0; j < width; j++)
{
if (*(data+widthi+j) == 1)
*(fontdataptr+modi+((offset+j)>>3)) |= 128>>((offset+j)&7);
}
}
(cd+dest)->charOffset = offset;
(cd+dest)->charBitWidth = width;
*off += width;
}